/*
 * Copyright (c)  2008 Sebastien Tremblay
 *
 * id3-tag-builder - helpers.TriStateCheckBox.java
 *
 * All source and documentation is copyrighted by Sebastien Tremblay
 * (seb at ryders dot net) and made available under the Apache License 2.0.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * $Id: TriStateCheckBox.java 30 2010-01-08 04:01:06Z ryders $
 */
package com.empireone.id3tagbuilder.gui.tree;

import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Paint;

import javax.swing.Icon;
import javax.swing.JCheckBox;
import javax.swing.JToggleButton;
import javax.swing.LookAndFeel;
import javax.swing.UIManager;

/**
 *
 * @author Sebastien Tremblay
 */
public class TriStateCheckBox extends JCheckBox {

    private static final long serialVersionUID = 1L;

    /**
     *
     */
    public static enum State {

	/**
	 *
	 */
	CHECKED,
	/**
	 * 
	 */
	UNCHECKED,
	/**
	 *
	 */
	PARTIAL
    };

    /**
     * Creates an initially unselected check box button with no text, no icon.
     */
    public TriStateCheckBox() {
	this(null, State.UNCHECKED);
    }

    /**
     * Creates a check box with text and icon, and specifies whether or not it is initially
     * selected.
     *
     * @param text
     *            The text of the check box.
     * @param initial
     *            The initial state
     */
    public TriStateCheckBox(String text, State initial) {
	super(text, initial == State.CHECKED);
	setModel(new TriStateModel(initial));
	setIcon(new TriStateIcon(this));
	// some UI settings
	//setRolloverEnabled(false);
    }

    /**
     * Set the new state to either CHECKED, PARTIAL or UNCHECKED.
     * @param state
     */
    public void setState(State state) {
	((TriStateModel) model).setState(state);
    }

    /**
     * Return the current state, which is determined by the selection status of the model.
     * @return
     */
    public State getState() {
	return ((TriStateModel) model).getState();
    }

    /*@Override
    public void setSelected(boolean selected) {
    ((TriStateModel) model).setSelected(selected);
    }*/
    /** The model for the button */
    private static class TriStateModel extends JToggleButton.ToggleButtonModel {

	private static final long serialVersionUID = 1L;
	protected State state;

	public TriStateModel(State state) {
	    this.state = state;
	}

	@Override
	public boolean isSelected() {
	    return state == State.CHECKED;
	}

	public State getState() {
	    return state;
	}

	public void setState(State state) {
	    this.state = state;
	    fireStateChanged();
	}

	@Override
	public void setPressed(boolean pressed) {
	    if (pressed) {
		switch (state) {
		    case UNCHECKED:
			state = State.CHECKED;
			break;
		    case PARTIAL:
			state = State.UNCHECKED;
			break;
		    case CHECKED:
			state = State.PARTIAL;
			break;
		}
	    }
	}

	@Override
	public void setSelected(boolean selected) {
	    if (selected) {
		state = State.CHECKED;
	    } else {
		state = State.UNCHECKED;
	    }
	}
    }

    private class TriStateIcon implements Icon {

	private Icon checkBoxIcon;
	private TriStateCheckBox triStateCheckBox;

	public TriStateIcon(TriStateCheckBox triStateCheckBox) {
	    this.triStateCheckBox = triStateCheckBox;
	    this.checkBoxIcon = UIManager.getIcon("CheckBox.icon");
	    return;
	}

	@Override
	public final int getIconHeight() {
	    return this.checkBoxIcon.getIconHeight();

	}

	@Override
	public final int getIconWidth() {
	    return this.checkBoxIcon.getIconWidth();

	}

	@Override
	public void paintIcon(Component c, Graphics g, int x, int y) {
	    checkBoxIcon.paintIcon(triStateCheckBox, g, x, y);
	    Graphics2D g2d = (Graphics2D) g;


	    if (triStateCheckBox.getState().equals(TriStateCheckBox.State.PARTIAL)) {
		LookAndFeel laf = UIManager.getLookAndFeel();
		Paint gradient = Color.GREEN.darker();
		int deltaX = 3;
		int deltaY = 3;

		if (laf.getName().equalsIgnoreCase("metal")) {
		    gradient = Color.BLACK;
		    deltaX--;
		    deltaY--;
		} else if (laf.getName().equalsIgnoreCase("cde/motif")) {
		    gradient = new Color(178, 77, 122);
		    deltaX--;
		    deltaY--;
		} else if (laf.getName().equalsIgnoreCase("nimbus")) {
		    gradient = new Color(57, 105, 138);
		    deltaX += 2;
		    deltaY += 2;
		}
		g2d.setPaint(gradient);
		g2d.fillRect(x + deltaX, y + deltaY, getIconWidth() - 2 * deltaX, getIconHeight() - 2 * deltaY);
	    }
	}
    }
}
